import { Card, CardSuit, CardRank, CardPattern, SUIT_NAMES, RANK_NAMES } from '../types/card'

// 根据接口文档的扑克牌ID映射表
const CARD_ID_MAP: Record<number, { suit: CardSuit; rank: CardRank }> = {
  // 方块 (suit=1)
  256: { suit: CardSuit.DIAMOND, rank: CardRank.TWO },    // 2
  257: { suit: CardSuit.DIAMOND, rank: CardRank.THREE },  // 3
  258: { suit: CardSuit.DIAMOND, rank: CardRank.FOUR },   // 4
  259: { suit: CardSuit.DIAMOND, rank: CardRank.FIVE },   // 5
  260: { suit: CardSuit.DIAMOND, rank: CardRank.SIX },    // 6
  261: { suit: CardSuit.DIAMOND, rank: CardRank.SEVEN },  // 7
  262: { suit: CardSuit.DIAMOND, rank: CardRank.EIGHT },  // 8
  263: { suit: CardSuit.DIAMOND, rank: CardRank.NINE },   // 9
  264: { suit: CardSuit.DIAMOND, rank: CardRank.TEN },    // 10
  265: { suit: CardSuit.DIAMOND, rank: CardRank.JACK },   // J
  266: { suit: CardSuit.DIAMOND, rank: CardRank.QUEEN },  // Q
  267: { suit: CardSuit.DIAMOND, rank: CardRank.KING },   // K
  268: { suit: CardSuit.DIAMOND, rank: CardRank.ACE },    // A

  // 梅花 (suit=2)
  512: { suit: CardSuit.CLUB, rank: CardRank.TWO },
  513: { suit: CardSuit.CLUB, rank: CardRank.THREE },
  514: { suit: CardSuit.CLUB, rank: CardRank.FOUR },
  515: { suit: CardSuit.CLUB, rank: CardRank.FIVE },
  516: { suit: CardSuit.CLUB, rank: CardRank.SIX },
  517: { suit: CardSuit.CLUB, rank: CardRank.SEVEN },
  518: { suit: CardSuit.CLUB, rank: CardRank.EIGHT },
  519: { suit: CardSuit.CLUB, rank: CardRank.NINE },
  520: { suit: CardSuit.CLUB, rank: CardRank.TEN },
  521: { suit: CardSuit.CLUB, rank: CardRank.JACK },
  522: { suit: CardSuit.CLUB, rank: CardRank.QUEEN },
  523: { suit: CardSuit.CLUB, rank: CardRank.KING },
  524: { suit: CardSuit.CLUB, rank: CardRank.ACE },

  // 红桃 (suit=3)
  768: { suit: CardSuit.HEART, rank: CardRank.TWO },
  769: { suit: CardSuit.HEART, rank: CardRank.THREE },
  770: { suit: CardSuit.HEART, rank: CardRank.FOUR },
  771: { suit: CardSuit.HEART, rank: CardRank.FIVE },
  772: { suit: CardSuit.HEART, rank: CardRank.SIX },
  773: { suit: CardSuit.HEART, rank: CardRank.SEVEN },
  774: { suit: CardSuit.HEART, rank: CardRank.EIGHT },
  775: { suit: CardSuit.HEART, rank: CardRank.NINE },
  776: { suit: CardSuit.HEART, rank: CardRank.TEN },
  777: { suit: CardSuit.HEART, rank: CardRank.JACK },
  778: { suit: CardSuit.HEART, rank: CardRank.QUEEN },
  779: { suit: CardSuit.HEART, rank: CardRank.KING },
  780: { suit: CardSuit.HEART, rank: CardRank.ACE },

  // 黑桃 (suit=4)
  1024: { suit: CardSuit.SPADE, rank: CardRank.TWO },
  1025: { suit: CardSuit.SPADE, rank: CardRank.THREE },
  1026: { suit: CardSuit.SPADE, rank: CardRank.FOUR },
  1027: { suit: CardSuit.SPADE, rank: CardRank.FIVE },
  1028: { suit: CardSuit.SPADE, rank: CardRank.SIX },
  1029: { suit: CardSuit.SPADE, rank: CardRank.SEVEN },
  1030: { suit: CardSuit.SPADE, rank: CardRank.EIGHT },
  1031: { suit: CardSuit.SPADE, rank: CardRank.NINE },
  1032: { suit: CardSuit.SPADE, rank: CardRank.TEN },
  1033: { suit: CardSuit.SPADE, rank: CardRank.JACK },
  1034: { suit: CardSuit.SPADE, rank: CardRank.QUEEN },
  1035: { suit: CardSuit.SPADE, rank: CardRank.KING },
  1036: { suit: CardSuit.SPADE, rank: CardRank.ACE },

  // 大小王
  1037: { suit: CardSuit.SMALL_JOKER, rank: CardRank.SMALL_JOKER }, // 小王
  1294: { suit: CardSuit.BIG_JOKER, rank: CardRank.BIG_JOKER }      // 大王
}

/**
 * 根据牌ID创建扑克牌对象
 */
export function createCardFromId(id: number): Card {
  const cardInfo = CARD_ID_MAP[id]
  if (!cardInfo) {
    throw new Error(`Invalid card ID: ${id}`)
  }

  return {
    id,
    suit: cardInfo.suit,
    rank: cardInfo.rank,
    display: getCardDisplay(cardInfo.suit, cardInfo.rank)
  }
}

/**
 * 根据花色和面值创建扑克牌对象
 */
export function createCard(suit: CardSuit, rank: CardRank): Card {
  const id = calculateCardId(suit, rank)
  return {
    id,
    suit,
    rank,
    display: getCardDisplay(suit, rank)
  }
}

/**
 * 计算扑克牌ID (根据公式: (suit << 8) + rank)
 */
export function calculateCardId(suit: CardSuit, rank: CardRank): number {
  if (suit === CardSuit.SMALL_JOKER) return 1037
  if (suit === CardSuit.BIG_JOKER) return 1294
  return (suit << 8) + rank
}

/**
 * 将当前系统的卡牌ID转换为API格式ID
 *
 * 当前系统ID格式（两副牌）：
 * - 第一副：256-268(方块), 512-524(梅花), 768-780(红桃), 1024-1036(黑桃), 1037(小王), 1294(大王)
 * - 第二副：10256-10268(方块), 10512-10524(梅花), 10768-10780(红桃), 11024-11036(黑桃), 11037(小王), 11294(大王)
 *
 * API格式ID
 * - 方块: 0-12
 * - 梅花: 256-268
 * - 红桃: 512-524
 * - 黑桃: 768-780
 * - 小王: 1037
 * - 大王: 1294
 *
 * 注意：第二副牌的ID会被映射到第一副牌的API格式范围内
 */
export function convertToAPICardId(currentId: number): number {
  // 大小王特殊处理
  if (currentId === 1037 || currentId === 11037) {
    return 1037  // 两副的小王都映射到1037
  }
  if (currentId === 1294 || currentId === 11294) {
    return 1294  // 两副的大王都映射到1294
  }

  // 第二副牌：先减去10000，转换为第一副牌的ID，再进行转换
  if (currentId >= 10000) {
    const firstDeckId = currentId - 10000
    return convertToAPICardId(firstDeckId)
  }

  // 第一副牌转换
  // 提取suit和rank
  const suit = (currentId >> 8) & 0xFF  // 高8位是suit
  const rank = currentId & 0xFF         // 低8位是rank

  // 验证suit和rank的有效性
  if (suit < 1 || suit > 4) {
    throw new Error(`Invalid suit in card ID: ${currentId} (suit=${suit})`)
  }
  if (rank < 0 || rank > 12) {
    throw new Error(`Invalid rank in card ID: ${currentId} (rank=${rank})`)
  }

  // 转换公式: API_ID = (suit - 1) * 256 + rank
  // suit=1(方块) -> (1-1)*256 + rank = rank (0-12)
  // suit=2(梅花) -> (2-1)*256 + rank = 256 + rank (256-268)
  // suit=3(红桃) -> (3-1)*256 + rank = 512 + rank (512-524)
  // suit=4(黑桃) -> (4-1)*256 + rank = 768 + rank (768-780)
  const apiId = (suit - 1) * 256 + rank

  console.log(`卡牌ID转换: 系统ID=${currentId} (suit=${suit}, rank=${rank}) -> API ID=${apiId}`)

  return apiId
}

/**
 * 将API格式ID转换回当前系统的卡牌ID
 *
 * API ID -> 系统ID反向转换
 */
export function convertFromAPICardId(apiId: number): number {
  // 大小王保持不变
  if (apiId === 1037 || apiId === 1294) {
    return apiId
  }

  // 提取suit和rank
  let suit: number
  let rank: number

  if (apiId >= 0 && apiId <= 12) {
    // 方块 (0-12)
    suit = 1  // CardSuit.DIAMOND
    rank = apiId
  } else if (apiId >= 256 && apiId <= 268) {
    // 梅花 (256-268)
    suit = 2  // CardSuit.CLUB
    rank = apiId - 256
  } else if (apiId >= 512 && apiId <= 524) {
    // 红桃 (512-524)
    suit = 3  // CardSuit.HEART
    rank = apiId - 512
  } else if (apiId >= 768 && apiId <= 780) {
    // 黑桃 (768-780)
    suit = 4  // CardSuit.SPADE
    rank = apiId - 768
  } else {
    throw new Error(`Invalid API card ID for conversion: ${apiId}`)
  }

  // 系统ID = (suit << 8) + rank
  const systemId = (suit << 8) + rank

  console.log(`API ID转换: API ID=${apiId} -> 系统ID=${systemId} (suit=${suit}, rank=${rank})`)

  return systemId
}

/**
 * 判断一张牌是否是级牌
 */
export function isLevelCard(card: Card, levelCard?: Card | null): boolean {
  if (!levelCard) return false
  return card.rank === levelCard.rank
}

/**
 * 级牌配牌信息
 */
interface WildcardAssignment {
  rank: CardRank  // 配成的rank
  suit: CardSuit  // 配成的花色
}

/**
 * 根据顺子推断级牌应该配成什么牌
 * @param cards 顺子中的所有牌（包括级牌）
 * @param levelCard 级牌定义
 * @returns 级牌应该配成的牌（rank和suit），如果无法推断则返回null
 */
/**
 * 判断一张牌是否是配牌（逢人配）
 * 掼蛋配牌规则：只有红桃的级牌可以作为配牌（通配牌）
 * 例如：级牌是9时，只有红桃9可以配任意牌
 */
export function isMatchingCard(card: Card, levelCard: Card | null): boolean {
  if (!levelCard) return false
  // 只有红桃花色的级牌才能作为配牌
  return card.rank === levelCard.rank && card.suit === CardSuit.HEART
}

export function inferWildcardRankInStraight(cards: Card[], levelCard: Card | null): Map<number, WildcardAssignment> | null {
  if (!levelCard || cards.length !== 5) return null

  // 分离级牌/配牌 和 非级牌
  const levelCards: Card[] = []
  const nonLevelCards: Card[] = []

  cards.forEach(card => {
    // 级牌或配牌都算作通配牌
    if (isLevelCard(card, levelCard) || isMatchingCard(card, levelCard)) {
      levelCards.push(card)
    } else {
      nonLevelCards.push(card)
    }
  })

  // 如果没有通配牌，不需要推断
  if (levelCards.length === 0) return null

  // 如果全是级牌，默认配成最高的同花顺（黑桃10-J-Q-K-A）
  if (nonLevelCards.length === 0) {
    const wildcardAssignments = new Map<number, WildcardAssignment>()
    cards.forEach((card, index) => {
      wildcardAssignments.set(card.id, {
        rank: CardRank.TEN + index as CardRank,
        suit: CardSuit.SPADE  // 黑桃最大
      })
    })
    return wildcardAssignments
  }

  // 检查非级牌是否同花色
  const firstSuit = nonLevelCards[0].suit
  const isSameSuit = nonLevelCards.every(card => card.suit === firstSuit)

  // 获取非级牌的rank，并排序
  const nonLevelRanks = nonLevelCards.map(c => c.rank).sort((a, b) => a - b)
  const minRank = nonLevelRanks[0]
  const maxRank = nonLevelRanks[nonLevelRanks.length - 1]

  // 计算顺子的可能范围
  // 顺子必须是5张连续的牌，所以范围是 [minRank, minRank+4]
  // 但也要考虑已有的最大rank
  const targetMinRank = Math.max(0, maxRank - 4)
  const targetMaxRank = Math.min(CardRank.ACE, minRank + 4)

  console.log('级牌配牌推断:', {
    levelCardsCount: levelCards.length,
    nonLevelRanks,
    minRank,
    maxRank,
    targetRange: [targetMinRank, targetMaxRank],
    isSameSuit,
    sameSuitValue: isSameSuit ? firstSuit : null
  })

  // 尝试找到一个连续的5张牌序列，优先往大配
  const wildcardAssignments = new Map<number, WildcardAssignment>()

  // 从大到小尝试
  for (let startRank = targetMaxRank - 4; startRank >= targetMinRank; startRank--) {
    const targetSequence = Array.from({ length: 5 }, (_, i) => startRank + i)

    // 检查非级牌是否都在这个序列中
    const allNonLevelInSequence = nonLevelRanks.every(rank => targetSequence.includes(rank))
    if (!allNonLevelInSequence) continue

    // 找到匹配的序列，计算级牌应该配成什么
    const missingRanks = targetSequence.filter(rank =>
      !nonLevelRanks.includes(rank)
    )

    if (missingRanks.length === levelCards.length) {
      // 按照"优先往大配"的原则，将级牌从大到小配牌
      const sortedMissingRanks = missingRanks.sort((a, b) => b - a)

      // 确定配牌的花色
      // 如果其他牌同花色，配成同花色（同花顺优先）
      // 如果其他牌不同花色，配成方块（普通顺子，方块ID最小）
      const targetSuit = isSameSuit ? firstSuit : CardSuit.DIAMOND

      // 将级牌按花色从大到小排序（黑桃>红桃>梅花>方块）
      // 往大配原则：花色大的级牌配成点数大的牌
      const sortedLevelCards = [...levelCards].sort((a, b) => b.suit - a.suit)

      sortedLevelCards.forEach((card, index) => {
        wildcardAssignments.set(card.id, {
          rank: sortedMissingRanks[index],
          suit: targetSuit
        })
      })

      console.log('找到配牌方案:', {
        targetSequence,
        missingRanks: sortedMissingRanks,
        targetSuit,
        isSameSuit,
        wildcardAssignments: Array.from(wildcardAssignments.entries()).map(([id, assignment]) => ({
          cardId: id,
          rank: assignment.rank,
          suit: assignment.suit
        }))
      })

      return wildcardAssignments
    }
  }

  // 特殊情况：A-2-3-4-5
  if (minRank <= CardRank.FIVE && nonLevelRanks.includes(CardRank.ACE)) {
    const a2345Sequence = [CardRank.ACE, CardRank.TWO, CardRank.THREE, CardRank.FOUR, CardRank.FIVE]
    const allNonLevelInA2345 = nonLevelRanks.every(rank => a2345Sequence.includes(rank))

    if (allNonLevelInA2345) {
      const missingRanks = a2345Sequence.filter(rank =>
        !nonLevelRanks.includes(rank)
      )

      if (missingRanks.length === levelCards.length) {
        const sortedMissingRanks = missingRanks.sort((a, b) => b - a)
        const targetSuit = isSameSuit ? firstSuit : CardSuit.DIAMOND

        // 将级牌按花色从大到小排序（黑桃>红桃>梅花>方块）
        // 往大配原则：花色大的级牌配成点数大的牌
        const sortedLevelCards = [...levelCards].sort((a, b) => b.suit - a.suit)

        sortedLevelCards.forEach((card, index) => {
          wildcardAssignments.set(card.id, {
            rank: sortedMissingRanks[index],
            suit: targetSuit
          })
        })

        console.log('找到A-2-3-4-5配牌方案:', {
          missingRanks: sortedMissingRanks,
          targetSuit,
          isSameSuit,
          wildcardAssignments: Array.from(wildcardAssignments.entries()).map(([id, assignment]) => ({
            cardId: id,
            rank: assignment.rank,
            suit: assignment.suit
          }))
        })

        return wildcardAssignments
      }
    }
  }

  console.warn('无法推断级牌配牌方案')
  return null
}

/**
 * 推断对子中的级牌配牌（往大配原则）
 * @returns Map<cardId, WildcardAssignment> 级牌应该配成什么
 */
export function inferWildcardInPair(cards: Card[], levelCard: Card | null): Map<number, WildcardAssignment> | null {
  if (!levelCard || cards.length !== 2) return null

  const levelCards = cards.filter(card => isLevelCard(card, levelCard) || isMatchingCard(card, levelCard))
  const nonLevelCards = cards.filter(card => !isLevelCard(card, levelCard) && !isMatchingCard(card, levelCard))

  if (levelCards.length === 0) return null

  // 对子的情况：
  // 1. 1个级牌 + 1张普通牌 → 级牌配成和普通牌相同
  // 2. 2个级牌 → 级牌配成A（最大牌）

  const assignments = new Map<number, WildcardAssignment>()

  if (levelCards.length === 1 && nonLevelCards.length === 1) {
    // 级牌配成和普通牌相同
    const targetCard = nonLevelCards[0]
    assignments.set(levelCards[0].id, {
      rank: targetCard.rank,
      suit: targetCard.suit
    })
  } else if (levelCards.length === 2) {
    // 2个级牌，配成一对A
    levelCards.forEach(card => {
      assignments.set(card.id, {
        rank: CardRank.ACE,
        suit: CardSuit.DIAMOND // 默认方块
      })
    })
  }

  console.log('对子级牌配牌推断:', Array.from(assignments.entries()).map(([id, assignment]) => ({
    cardId: id,
    targetRank: assignment.rank,
    targetSuit: assignment.suit
  })))

  return assignments
}

/**
 * 推断刻子中的级牌配牌（往大配原则）
 */
export function inferWildcardInTriple(cards: Card[], levelCard: Card | null): Map<number, WildcardAssignment> | null {
  if (!levelCard || cards.length !== 3) return null

  const levelCards = cards.filter(card => isLevelCard(card, levelCard) || isMatchingCard(card, levelCard))
  const nonLevelCards = cards.filter(card => !isLevelCard(card, levelCard) && !isMatchingCard(card, levelCard))

  if (levelCards.length === 0) return null

  const assignments = new Map<number, WildcardAssignment>()

  if (levelCards.length === 1 && nonLevelCards.length === 2) {
    // 1个级牌 + 2张普通牌 → 级牌配成和普通牌相同
    const targetCard = nonLevelCards[0]
    assignments.set(levelCards[0].id, {
      rank: targetCard.rank,
      suit: targetCard.suit
    })
  } else if (levelCards.length === 2 && nonLevelCards.length === 1) {
    // 2个级牌 + 1张普通牌 → 级牌配成和普通牌相同
    const targetCard = nonLevelCards[0]
    levelCards.forEach(card => {
      assignments.set(card.id, {
        rank: targetCard.rank,
        suit: targetCard.suit
      })
    })
  } else if (levelCards.length === 3) {
    // 3个级牌 → 配成三个A
    levelCards.forEach(card => {
      assignments.set(card.id, {
        rank: CardRank.ACE,
        suit: CardSuit.DIAMOND
      })
    })
  }

  console.log('刻子级牌配牌推断:', Array.from(assignments.entries()).map(([id, assignment]) => ({
    cardId: id,
    targetRank: assignment.rank,
    targetSuit: assignment.suit
  })))

  return assignments
}

/**
 * 推断三带二中的级牌配牌（往大配原则）
 */
export function inferWildcardInTripleWithPair(cards: Card[], levelCard: Card | null): Map<number, WildcardAssignment> | null {
  if (!levelCard || cards.length !== 5) return null

  const levelCards = cards.filter(card => isLevelCard(card, levelCard) || isMatchingCard(card, levelCard))
  const nonLevelCards = cards.filter(card => !isLevelCard(card, levelCard) && !isMatchingCard(card, levelCard))

  if (levelCards.length === 0) return null

  // 统计非级牌的rank计数
  const rankCounts = new Map<number, Card[]>()
  nonLevelCards.forEach(card => {
    if (!rankCounts.has(card.rank)) {
      rankCounts.set(card.rank, [])
    }
    rankCounts.get(card.rank)!.push(card)
  })

  const counts = Array.from(rankCounts.entries()).sort((a, b) => b[1].length - a[1].length)
  const assignments = new Map<number, WildcardAssignment>()

  // 往大配原则：
  // - 优先配成三张（三张 > 对子）
  // - 如果都配三张，选择rank大的配三张

  if (levelCards.length === 1) {
    if (counts.length === 2) {
      const [group1, group2] = counts
      if (group1[1].length === 3 && group2[1].length === 1) {
        // 3+1+1级 → 级牌配成对子（和单张相同）
        assignments.set(levelCards[0].id, {
          rank: group2[0],
          suit: group2[1][0].suit
        })
      } else if (group1[1].length === 2 && group2[1].length === 2) {
        // 2+2+1级 → 往大配：选rank大的配成三张
        const targetRank = Math.max(group1[0], group2[0])
        const targetGroup = group1[0] === targetRank ? group1[1] : group2[1]
        assignments.set(levelCards[0].id, {
          rank: targetRank,
          suit: targetGroup[0].suit
        })
      }
    }
  } else if (levelCards.length === 2) {
    if (counts.length === 2) {
      // 2+1+2级 → 往大配：选rank大的配成三张，另一个配成对子
      const [group1, group2] = counts
      const targetTripleRank = Math.max(group1[0], group2[0])
      const targetPairRank = Math.min(group1[0], group2[0])
      const tripleGroup = group1[0] === targetTripleRank ? group1[1] : group2[1]
      const pairGroup = group1[0] === targetPairRank ? group1[1] : group2[1]

      // 往大配原则：花色大的级牌配成三张，花色小的配成对子
      const sortedLevelCards = [...levelCards].sort((a, b) => b.suit - a.suit)

      // 花色大的级牌配三张
      assignments.set(sortedLevelCards[0].id, {
        rank: targetTripleRank,
        suit: tripleGroup[0].suit
      })
      // 花色小的级牌配对子
      assignments.set(sortedLevelCards[1].id, {
        rank: targetPairRank,
        suit: pairGroup[0].suit
      })
    } else if (counts.length === 1) {
      // 3+2级 → 2个级牌配成对子（和三张相同）
      const targetRank = counts[0][0]
      const targetSuit = counts[0][1][0].suit
      levelCards.forEach(card => {
        assignments.set(card.id, {
          rank: targetRank,
          suit: targetSuit
        })
      })
    }
  } else if (levelCards.length === 3) {
    // 2+3级 → 3个级牌配成三张（和对子相同）
    if (counts.length === 1) {
      const targetRank = counts[0][0]
      const targetSuit = counts[0][1][0].suit
      levelCards.forEach(card => {
        assignments.set(card.id, {
          rank: targetRank,
          suit: targetSuit
        })
      })
    }
  } else if (levelCards.length === 4) {
    // 1+4级 → 往大配：配成AAA+22 (3个A+2个单张)
    if (nonLevelCards.length === 1) {
      const singleRank = nonLevelCards[0].rank

      // 往大配原则：花色大的级牌配成A（三张），花色小的配成对子
      const sortedLevelCards = [...levelCards].sort((a, b) => b.suit - a.suit)

      // 前3个级牌配成A（三张）
      for (let i = 0; i < 3; i++) {
        assignments.set(sortedLevelCards[i].id, {
          rank: CardRank.ACE,
          suit: CardSuit.DIAMOND
        })
      }
      // 最后1个级牌配成和单张相同（对子）
      assignments.set(sortedLevelCards[3].id, {
        rank: singleRank,
        suit: nonLevelCards[0].suit
      })
    }
  } else if (levelCards.length === 5) {
    // 5个级牌 → 配成AAA+22（全A也行，但这里配成AAA+AA更合理）
    levelCards.forEach(card => {
      assignments.set(card.id, {
        rank: CardRank.ACE,
        suit: CardSuit.DIAMOND
      })
    })
  }

  console.log('三带二级牌配牌推断:', Array.from(assignments.entries()).map(([id, assignment]) => ({
    cardId: id,
    targetRank: assignment.rank,
    targetSuit: assignment.suit
  })))

  return assignments
}

/**
 * 推断炸弹中的级牌配牌（往大配原则）
 */
export function inferWildcardInBomb(cards: Card[], levelCard: Card | null): Map<number, WildcardAssignment> | null {
  if (!levelCard || cards.length < 4) return null

  const levelCards = cards.filter(card => isLevelCard(card, levelCard) || isMatchingCard(card, levelCard))
  const nonLevelCards = cards.filter(card => !isLevelCard(card, levelCard) && !isMatchingCard(card, levelCard))

  if (levelCards.length === 0) return null

  const assignments = new Map<number, WildcardAssignment>()

  if (nonLevelCards.length > 0) {
    // 有非级牌，级牌配成和非级牌相同
    const targetCard = nonLevelCards[0]
    levelCards.forEach(card => {
      assignments.set(card.id, {
        rank: targetCard.rank,
        suit: targetCard.suit
      })
    })
  } else {
    // 全是级牌，配成A炸
    levelCards.forEach(card => {
      assignments.set(card.id, {
        rank: CardRank.ACE,
        suit: CardSuit.DIAMOND
      })
    })
  }

  console.log(`${cards.length}炸级牌配牌推断:`, Array.from(assignments.entries()).map(([id, assignment]) => ({
    cardId: id,
    targetRank: assignment.rank,
    targetSuit: assignment.suit
  })))

  return assignments
}

/**
 * 推断木板中的级牌配牌（往大配原则）
 * 木板：两个三张
 */
export function inferWildcardInWoodBoard(cards: Card[], levelCard: Card | null): Map<number, WildcardAssignment> | null {
  if (!levelCard || cards.length !== 6) return null

  const levelCards = cards.filter(card => isLevelCard(card, levelCard) || isMatchingCard(card, levelCard))
  const nonLevelCards = cards.filter(card => !isLevelCard(card, levelCard) && !isMatchingCard(card, levelCard))

  if (levelCards.length === 0) return null

  // 统计非级牌的rank计数
  const rankCounts = new Map<number, Card[]>()
  nonLevelCards.forEach(card => {
    if (!rankCounts.has(card.rank)) {
      rankCounts.set(card.rank, [])
    }
    rankCounts.get(card.rank)!.push(card)
  })

  const counts = Array.from(rankCounts.entries()).sort((a, b) => {
    // 先按数量降序，再按rank降序
    if (b[1].length !== a[1].length) {
      return b[1].length - a[1].length
    }
    return b[0] - a[0]
  })

  const assignments = new Map<number, WildcardAssignment>()

  // 往大配：优先配rank大的三张
  if (levelCards.length === 1) {
    // 3+2+1级 或其他情况
    if (counts.length === 2 && counts[0][1].length === 3 && counts[1][1].length === 2) {
      // 3+2+1级 → 配成3+3
      const targetRank = counts[1][0]
      const targetSuit = counts[1][1][0].suit
      assignments.set(levelCards[0].id, {
        rank: targetRank,
        suit: targetSuit
      })
    }
  } else if (levelCards.length === 2) {
    // 多种情况
    if (counts.length === 2) {
      const [group1] = counts
      // 选择rank大的配成3
      const targetRank = group1[0]
      const targetSuit = group1[1][0].suit
      levelCards.forEach(card => {
        assignments.set(card.id, {
          rank: targetRank,
          suit: targetSuit
        })
      })
    } else if (counts.length === 1 && counts[0][1].length === 4) {
      // 4+2级 → 配成3+3
      const targetRank = counts[0][0]
      const targetSuit = counts[0][1][0].suit
      levelCards.forEach(card => {
        assignments.set(card.id, {
          rank: targetRank,
          suit: targetSuit
        })
      })
    }
  } else if (levelCards.length >= 3) {
    // 更多级牌，往大配
    if (counts.length === 1) {
      // 只有一个rank，全配成这个
      const targetRank = counts[0][0]
      const targetSuit = counts[0][1][0].suit
      levelCards.forEach(card => {
        assignments.set(card.id, {
          rank: targetRank,
          suit: targetSuit
        })
      })
    } else if (counts.length === 0) {
      // 全是级牌，配成A+A
      levelCards.forEach(card => {
        assignments.set(card.id, {
          rank: CardRank.ACE,
          suit: CardSuit.DIAMOND
        })
      })
    }
  }

  console.log('木板级牌配牌推断:', Array.from(assignments.entries()).map(([id, assignment]) => ({
    cardId: id,
    targetRank: assignment.rank,
    targetSuit: assignment.suit
  })))

  return assignments
}

/**
 * 推断钢板中的级牌配牌（往大配原则）
 * 钢板：三对连对
 */
export function inferWildcardInSteelBoard(cards: Card[], levelCard: Card | null): Map<number, WildcardAssignment> | null {
  if (!levelCard || cards.length !== 6) return null

  const levelCards = cards.filter(card => isLevelCard(card, levelCard) || isMatchingCard(card, levelCard))
  const nonLevelCards = cards.filter(card => !isLevelCard(card, levelCard) && !isMatchingCard(card, levelCard))

  if (levelCards.length === 0) return null

  // 统计非级牌的rank计数
  const rankCounts = new Map<number, Card[]>()
  nonLevelCards.forEach(card => {
    if (!rankCounts.has(card.rank)) {
      rankCounts.set(card.rank, [])
    }
    rankCounts.get(card.rank)!.push(card)
  })

  const counts = Array.from(rankCounts.entries()).sort((a, b) => b[0] - a[0]) // 按rank降序

  const assignments = new Map<number, WildcardAssignment>()

  // 往大配：配成最大的连对
  // 简化处理：直接配成rank最大的几对
  if (levelCards.length === 1) {
    // 找一个单张，配成对子
    const singleRankGroup = counts.find(g => g[1].length === 1)
    if (singleRankGroup) {
      assignments.set(levelCards[0].id, {
        rank: singleRankGroup[0],
        suit: singleRankGroup[1][0].suit
      })
    }
  } else if (levelCards.length === 2) {
    // 配成一个新对子（往大配，选A）
    levelCards.forEach(card => {
      assignments.set(card.id, {
        rank: CardRank.ACE,
        suit: CardSuit.DIAMOND
      })
    })
  } else {
    // 更多级牌，往大配
    levelCards.forEach(card => {
      assignments.set(card.id, {
        rank: CardRank.ACE,
        suit: CardSuit.DIAMOND
      })
    })
  }

  console.log('钢板级牌配牌推断:', Array.from(assignments.entries()).map(([id, assignment]) => ({
    cardId: id,
    targetRank: assignment.rank,
    targetSuit: assignment.suit
  })))

  return assignments
}

/**
 * 按照掼蛋规则对API ID进行排序
 * 规则：
 * 1. 先按点数（rank）从小到大排序
 * 2. 同点数时按花色（suit）从小到大排序（方块 < 梅花 < 红桃 < 黑桃）
 * 3. 大小王放在最后（小王 < 大王）
 */
function sortAPIIdsByGuandanRules(apiIds: number[]): number[] {
  return [...apiIds].sort((a, b) => {
    // 大小王特殊处理（放在最后）
    if (a === 1294) return 1  // 大王最大
    if (b === 1294) return -1
    if (a === 1037) return 1  // 小王次之
    if (b === 1037) return -1

    // 从API ID提取 suit 和 rank
    // API ID公式: (suit - 1) * 256 + rank
    const suitA = Math.floor(a / 256) + 1  // suit范围: 1-4
    const rankA = a % 256                   // rank范围: 0-12
    const suitB = Math.floor(b / 256) + 1
    const rankB = b % 256

    // 先按点数排序
    if (rankA !== rankB) {
      return rankA - rankB
    }

    // 点数相同时按花色排序
    return suitA - suitB
  })
}

/**
 * 批量转换卡牌ID到API格式
 * @param cards 要转换的牌
 * @param levelCard 级牌（用于推断通配牌配牌）
 * @param cardCombination 牌型组合（用于判断是否需要配牌）
 * @returns 排序后的API ID数组（按掼蛋规则：点数优先，同点数按花色）
 */
export function convertCardsToAPIIds(
  cards: Card[],
  levelCard?: Card | null,
  cardCombination?: { type: CardPattern } | null
): number[] {
  let apiIds: number[]

  if (!cardCombination || !levelCard) {
    // 没有牌型信息或级牌，正常转换
    console.log('未使用配牌转换，正常转换')
    apiIds = cards.map(card => convertToAPICardId(card.id))
  } else {
    // 根据牌型选择对应的级牌配牌推断函数
    let wildcardAssignments: Map<number, WildcardAssignment> | null = null
    let patternName = ''

    switch (cardCombination.type) {
      case CardPattern.PAIR:
        wildcardAssignments = inferWildcardInPair(cards, levelCard)
        patternName = '对子(2)'
        break

      case CardPattern.TRIPLE:
        wildcardAssignments = inferWildcardInTriple(cards, levelCard)
        patternName = '刻子(3)'
        break

      case CardPattern.TRIPLE_WITH_PAIR:
        wildcardAssignments = inferWildcardInTripleWithPair(cards, levelCard)
        patternName = '三带二(4)'
        break

      case CardPattern.WOOD_BOARD:
        wildcardAssignments = inferWildcardInWoodBoard(cards, levelCard)
        patternName = '木板(5)'
        break

      case CardPattern.STEEL_BOARD:
        wildcardAssignments = inferWildcardInSteelBoard(cards, levelCard)
        patternName = '钢板(6)'
        break

      case CardPattern.STRAIGHT:
        wildcardAssignments = inferWildcardRankInStraight(cards, levelCard)
        patternName = '顺子(7)'
        break

      case CardPattern.FOUR_BOMB:
      case CardPattern.FIVE_BOMB:
      case CardPattern.SIX_BOMB:
      case CardPattern.SEVEN_BOMB:
      case CardPattern.EIGHT_BOMB:
      case CardPattern.NINE_BOMB:
      case CardPattern.TEN_BOMB:
        wildcardAssignments = inferWildcardInBomb(cards, levelCard)
        patternName = `${cards.length}炸(${8 + cards.length - 4})`
        break

      case CardPattern.SAME_SUIT_STRAIGHT:
        wildcardAssignments = inferWildcardRankInStraight(cards, levelCard)
        patternName = '同花顺(10)'
        break

      case CardPattern.KING_BOMB:
        // 天王炸不需要配牌转换（大小王组合）
        patternName = '天王炸(16)'
        break

      default:
        // 其他牌型（单牌等）不需要配牌转换
        break
    }

    // 如果有级牌配牌方案，进行转换
    if (wildcardAssignments && wildcardAssignments.size > 0) {
      console.log(`=== 级牌配牌转换: ${patternName} ===`)

      apiIds = cards.map(card => {
        const assignment = wildcardAssignments!.get(card.id)

        if (assignment !== undefined) {
          // 这是级牌，需要配牌
          // 级牌配成什么牌，就传什么牌的API ID
          // 注意：级牌按当前级牌的颜色花色传递（不再转换花色）
          let suitForApi = assignment.suit
          if (levelCard && card.rank === levelCard.rank) {
            suitForApi = levelCard.suit
          }
          const targetApiId = (suitForApi - 1) * 256 + assignment.rank

          console.log(`  级牌配牌: ${card.display} (${card.id}) 配成 suit=${assignment.suit} rank=${assignment.rank}, 实际传递花色=${suitForApi} -> API ID=${targetApiId}`)

          return targetApiId
        } else {
          // 非级牌，正常转换
          const apiId = convertToAPICardId(card.id)
          console.log(`  普通牌: ${card.display} (${card.id}) -> API ID=${apiId}`)
          return apiId
        }
      })
    } else {
      // 没有级牌或无需配牌，正常转换
      if (patternName) {
        console.log(`=== 无级牌配牌: ${patternName} ===`)
      }
      apiIds = cards.map(card => convertToAPICardId(card.id))
    }
  }

  // 按照掼蛋规则排序（点数优先，同点数按花色）
  const sortedIds = sortAPIIdsByGuandanRules(apiIds)
  console.log(`=== API ID排序 ===`)
  console.log(`排序前: [${apiIds.join(', ')}]`)
  console.log(`排序后: [${sortedIds.join(', ')}]`)

  return sortedIds
}

/**
 * 批量转换API格式ID到卡牌对象
 */
export function convertAPIIdsToCards(apiIds: number[]): Card[] {
  return apiIds.map(apiId => {
    const currentId = convertFromAPICardId(apiId)
    return createCardFromId(currentId)
  })
}

/**
 * 获取掼蛋中牌的显示顺序值
 * 在掼蛋中，级牌的大小仅次于2
 * 例如：级牌是9时，顺序是 3<4<5<6<7<8<10<J<Q<K<A<9<2<小王<大王
 */
function getGuandanDisplayOrder(rank: CardRank, levelRank?: CardRank): number {
  // 大小王
  if (rank === CardRank.SMALL_JOKER) return 100
  if (rank === CardRank.BIG_JOKER) return 101

  // 2最大（仅次于王）
  if (rank === CardRank.TWO) return 15

  // 级牌次之（仅次于2）
  if (levelRank && rank === levelRank) return 14

  // A
  if (rank === CardRank.ACE) return 13

  // K-3按正常顺序
  // K=12, Q=11, J=10, 10=9, 9=8, 8=7, 7=6, 6=5, 5=4, 4=3, 3=2
  return rank - 1
}

/**
 * 按照掼蛋规则对Card数组进行排序
 * 规则：
 * 1. 先按掼蛋显示顺序从小到大排序（考虑级牌特殊顺序）
 * 2. 同点数时按花色（suit）从小到大排序（方块 < 梅花 < 红桃 < 黑桃）
 * 3. 大小王放在最后（小王 < 大王）
 * 4. 如果提供了级牌，配牌会按照它实际配成的牌进行排序
 *
 * @param cards 要排序的牌
 * @param levelCard 级牌（可选，用于正确排序配牌）
 */
export function sortCardsByGuandanRules(cards: readonly Card[], levelCard?: Card | null): Card[] {
  // 如果数组为空，直接返回空数组
  if (!cards || cards.length === 0) {
    return []
  }

  // 创建一个深拷贝的可变副本
  const mutableCards = Array.from(cards).map(card => ({
    id: card.id,
    suit: card.suit,
    rank: card.rank,
    display: card.display
  }))

  // 获取级牌的点数（用于判断配牌）
  const levelRank = levelCard?.rank

  // 判断一张牌是否是级牌
  const isLevel = (card: Card): boolean => {
    if (!levelCard || !levelRank) return false
    return card.rank === levelRank
  }

  // 判断一张牌是否是配牌（使用全局函数）
  const isMatching = (card: Card): boolean => {
    return isMatchingCard(card, levelCard ?? null)
  }

  // 尝试推断配牌在这组牌中实际配成了什么
  let wildcardAssignments: Map<number, WildcardAssignment> | null = null
  if (levelCard) {
    if (mutableCards.length === 2) {
      // 对子
      wildcardAssignments = inferWildcardInPair(mutableCards, levelCard)
    } else if (mutableCards.length === 3) {
      // 刻子
      wildcardAssignments = inferWildcardInTriple(mutableCards, levelCard)
    } else if (mutableCards.length === 5) {
      // 可能是顺子或三带二
      const tripleWithPair = inferWildcardInTripleWithPair(mutableCards, levelCard)
      if (tripleWithPair) {
        wildcardAssignments = tripleWithPair
      } else {
        wildcardAssignments = inferWildcardRankInStraight(mutableCards, levelCard)
      }
    } else if (mutableCards.length === 6) {
      // 可能是木板或钢板
      const steelBoard = inferWildcardInSteelBoard(mutableCards, levelCard)
      if (steelBoard) {
        wildcardAssignments = steelBoard
      } else {
        const woodBoard = inferWildcardInWoodBoard(mutableCards, levelCard)
        if (woodBoard) {
          wildcardAssignments = woodBoard
        }
      }
    }
  }

  // 计算牌的排序权重
  const getSortKey = (card: Card): number => {
    // 大小王特殊处理（放在最后）
    if (card.suit === CardSuit.BIG_JOKER) return 1000000  // 大王最大
    if (card.suit === CardSuit.SMALL_JOKER) return 999999  // 小王次之

    const levelFlag = isLevel(card)
    const matchingFlag = isMatching(card)

    // 如果推断出了配牌信息，使用推断的rank来排序
    if ((levelFlag || matchingFlag) && wildcardAssignments && wildcardAssignments.has(card.id)) {
      const assignment = wildcardAssignments.get(card.id)!
      // 配牌按照它实际配成的rank的掼蛋显示顺序排序，但稍微靠后一点（加0.5）
      const displayOrder = getGuandanDisplayOrder(assignment.rank, levelRank)
      return displayOrder * 1000 + assignment.suit + 0.5
    }

    // 普通牌按掼蛋显示顺序排序
    const displayOrder = getGuandanDisplayOrder(card.rank, levelRank)
    return displayOrder * 1000 + card.suit
  }

  // 执行排序
  mutableCards.sort((a, b) => {
    return getSortKey(a) - getSortKey(b)
  })

  return mutableCards
}

/**
 * 获取扑克牌显示文本
 */
export function getCardDisplay(suit: CardSuit, rank: CardRank): string {
  if (suit === CardSuit.SMALL_JOKER || suit === CardSuit.BIG_JOKER) {
    return RANK_NAMES[rank]
  }
  return `${SUIT_NAMES[suit]}${RANK_NAMES[rank]}`
}

/**
 * 生成完整的扑克牌组 (54张牌)
 */
export function generateFullDeck(): Card[] {
  const cards: Card[] = []

  // 生成四种花色的牌 (每种13张)
  for (let suit = CardSuit.DIAMOND; suit <= CardSuit.SPADE; suit++) {
    for (let rank = CardRank.TWO; rank <= CardRank.ACE; rank++) {
      cards.push(createCard(suit, rank))
    }
  }

  // 添加大小王
  cards.push(createCard(CardSuit.SMALL_JOKER, CardRank.SMALL_JOKER))
  cards.push(createCard(CardSuit.BIG_JOKER, CardRank.BIG_JOKER))

  return cards
}

/**
 * 生成两副扑克牌组 (108张牌)
 */
export function generateDoubleDeck(): Card[] {
  const cards: Card[] = []

  // 先生成第一副牌，使用正确的ID映射
  const firstDeck = generateFullDeck()
  cards.push(...firstDeck)

  // 生成第二副牌，ID加10000偏移
  for (let suit = CardSuit.DIAMOND; suit <= CardSuit.SPADE; suit++) {
    for (let rank = CardRank.TWO; rank <= CardRank.ACE; rank++) {
      const originalCard = createCard(suit, rank)
      cards.push({
        id: originalCard.id + 10000,
        suit,
        rank,
        display: getCardDisplay(suit, rank)
      })
    }
  }

  // 添加第二副大小王
  cards.push({
    id: 11037,
    suit: CardSuit.SMALL_JOKER,
    rank: CardRank.SMALL_JOKER,
    display: getCardDisplay(CardSuit.SMALL_JOKER, CardRank.SMALL_JOKER)
  })
  cards.push({
    id: 11294,
    suit: CardSuit.BIG_JOKER,
    rank: CardRank.BIG_JOKER,
    display: getCardDisplay(CardSuit.BIG_JOKER, CardRank.BIG_JOKER)
  })

  return cards
}

/**
 * 洗牌算法 (Fisher-Yates)
 */
export function shuffleCards(cards: Card[]): Card[] {
  const shuffled = [...cards]
  for (let i = shuffled.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1))
      ;[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
  }
  return shuffled
}

/**
 * 按牌力排序扑克牌
 */
export function sortCardsByPower(cards: Card[]): Card[] {
  return [...cards].sort((a, b) => {
    // 大小王最大
    if (a.suit === CardSuit.BIG_JOKER) return 1
    if (b.suit === CardSuit.BIG_JOKER) return -1
    if (a.suit === CardSuit.SMALL_JOKER) return 1
    if (b.suit === CardSuit.SMALL_JOKER) return -1

    // 按面值排序
    return a.rank - b.rank
  })
}

/**
 * 按花色分组扑克牌
 */
export function groupCardsBySuit(cards: Card[]): Record<CardSuit, Card[]> {
  const groups: Record<CardSuit, Card[]> = {
    [CardSuit.DIAMOND]: [],
    [CardSuit.CLUB]: [],
    [CardSuit.HEART]: [],
    [CardSuit.SPADE]: [],
    [CardSuit.SMALL_JOKER]: [],
    [CardSuit.BIG_JOKER]: []
  }

  cards.forEach(card => {
    groups[card.suit].push(card)
  })

  return groups
}

/**
 * 将牌ID数组转换为Card对象数组
 */
export function convertIdsToCards(ids: number[]): Card[] {
  return ids.map(id => createCardFromId(id))
}

/**
 * 将Card对象数组转换为牌ID数组
 */
export function convertCardsToIds(cards: Card[]): number[] {
  return cards.map(card => card.id)
}

/**
 * 检查两张牌是否相同
 */
export function areCardsEqual(card1: Card, card2: Card): boolean {
  return card1.id === card2.id
}

/**
 * 从牌组中移除指定的牌
 */
export function removeCardsFromDeck(deck: Card[], cardsToRemove: Card[]): Card[] {
  return deck.filter(card =>
    !cardsToRemove.some(removeCard => areCardsEqual(card, removeCard))
  )
}